#include "cameramanager.h"

CameraManager::CameraManager(CAMERA cameras, QObject *parent) : QObject(parent)
{
    m_camera = cameras;
}

void CameraManager::startEncode()
{
    m_udpRec->startProcess();  //开始接收数据
}

void CameraManager::stopEncode()
{
    m_udpRec->stopProcess();   //停止接收数据
}

void CameraManager::init()
{
    //获取配置文件内容
    QVector<ENCODE_PARAM> m_cfgs = MyIni::loadVideoConfigs();

    ENCODE_PARAM m_cfg = m_cfgs[static_cast<int>(m_camera)];

    //接收端初始化
    switch (m_camera) {
    case _airMidWV: {
        m_udpRec = new AirMidWVUdp();
        m_process = new ImageProcessor(640, 512, m_cfg._fps);
        m_udpRec->setTargetFps(m_cfg._fps);
        m_sender = new DataSender(640, 512, m_cfg._fps);
        break;
    }
    case _airVisble: {
        m_udpRec = new AirVisibleUdp();
        m_udpRec->setTargetFps(m_cfg._fps);
        m_sender = new DataSender(1920, 1080, m_cfg._fps);
        break;
    }
    case _groundLongWV: {
            m_udpRec = new GroundWVUdp(320, 256);
            m_process = new ImageProcessor(320, 256, m_cfg._fps);
            m_udpRec->setTargetFps(m_cfg._fps);
            m_sender = new DataSender(320, 256, m_cfg._fps);
        break;
    }
    case _groundMidWV: {
            m_udpRec = new GroundWVUdp(640, 512);
            m_process = new ImageProcessor(640, 512, m_cfg._fps);
            m_udpRec->setTargetFps(m_cfg._fps);
            m_sender = new DataSender(640, 512, m_cfg._fps);
        break;
    }
    default:
        return;
        break;
    }
    m_udpRec->setConfig(m_cfg);

    m_recThread = new QThread;
    m_udpRec->moveToThread(m_recThread);

    //如果是空中可见光（h264）就不进行编码处理
    if(m_camera != _airVisble) {
        //编码端初始化
        m_encodeThread = new QThread;
        m_process->moveToThread(m_encodeThread);
    }

    //发送端初始化
    m_sendThread = new QThread;

    m_sender->moveToThread(m_sendThread);

    m_sender->setDestination(m_cfg._dstIp, m_cfg._dstPort);  // 发送编码后数据的目标地址
    m_sender->setBindIpAndPort(m_cfg._bindIp, 12367);

    m_threads.append(m_recThread);
    m_threads.append(m_encodeThread);
    m_threads.append(m_sendThread);

    //建立连接
    connectObj();

    //开启线程
    m_recThread->start();

    m_encodeThread->start();

    m_sendThread->start();
}

void CameraManager::connectObj()
{
    //连接线程开始后，工作对象的初始化动作
    connect(m_recThread, &QThread::started, m_udpRec, &UdpBase::onInitUdp);
    connect(m_encodeThread, &QThread::started, m_process, &ImageProcessor::onInitEncoder);
    connect(m_sendThread, &QThread::started, m_sender, &DataSender::onInitUdp);

    //连接收到一帧完整的udp数据后，通知ffmpeg对象去编码
    connect(m_udpRec, &UdpBase::sigToEncodeImg, m_process, &ImageProcessor::onProcessImageData);

    //连接编码完，进行udp发送操作
    connect(m_process, &ImageProcessor::frameEncoded, m_sender, &DataSender::onSendData);

    //对于接收h264流，直接连接发送端转发
    connect(m_udpRec, &UdpBase::sigToSend, m_sender, &DataSender::onSendData);

    connect(m_sender, &DataSender::sigToShowUi, [=](int width, int height, int fps){
        emit sigToShowUi(m_camera, width, height, fps);
    });

    //连接错误处理
    connect(m_udpRec, &UdpBase::sigErrorOccurred, this, &CameraManager::sigErrorOccurred);
    connect(m_process, &ImageProcessor::errorOccurred, this, &CameraManager::sigErrorOccurred);
    connect(m_sender, &DataSender::errorOccurred, this, &CameraManager::sigErrorOccurred);
}


CameraManager::~CameraManager()
{
    for(int i = 0; i < m_threads.size(); i++) {
        m_threads[i]->quit();
        m_threads[i]->wait();
    }

    if(m_udpRec) {
        delete m_udpRec;
        m_udpRec = nullptr;
    }

    if(m_process) {
        delete m_process;
        m_process = nullptr;
    }

    if(m_sender) {
        delete m_sender;
        m_sender = nullptr;
    }
}

